/**
 * @file utils.h
 *
 * @brief Miscellaneous supplementary stuff
 *
 */

#ifndef UTILS_H_
#define UTILS_H_


#include <stdio.h>


typedef signed char             sint8_t;
typedef unsigned char           uint8_t;
typedef signed short            sint16_t;
typedef unsigned short          uint16_t;
typedef signed int              sint32_t;
typedef unsigned int            uint32_t;
typedef signed long long        sint64_t;
typedef unsigned long long      uint64_t;


/**
 * @brief Returns the number of seconds since the first call
 *
 * @return The number of seconds
 */
uint32_t cur_time(void);

/**
 * @brief Use the PID to set the window group id.
 *
 * @return String containing the window group id
 */
const char* get_window_group_id(void);


/* Logging facilities */
#define LOG_LEVEL_NONE          0
#define LOG_LEVEL_ERROR         1
#define LOG_LEVEL_WARNING       2
#define LOG_LEVEL_INFO          3
#define LOG_LEVEL_DEBUG         4

#ifndef LOG_LEVEL
    #define LOG_LEVEL           LOG_LEVEL_DEBUG     /* default log level */
#endif

#if LOG_LEVEL < LOG_LEVEL_ERROR
    #define LOG_ERR(fmt, ...)
#else
    #define LOG_ERR(fmt, ...)                                                                   \
        do {                                                                                    \
            uint32_t ct = cur_time();                                                           \
            fprintf(stderr, "%.2u:%.2u:%.2u ERR %s():%d\t"fmt"\n",                              \
                ct / 3600, (ct % 3600) / 60, ct % 60, __FUNCTION__, __LINE__, ##__VA_ARGS__);   \
        } while(0)
#endif

#if LOG_LEVEL < LOG_LEVEL_WARNING
    #define LOG_WRN(fmt, ...)
#else
    #define LOG_WRN(fmt, ...)                                                                   \
        do {                                                                                    \
            uint32_t ct = cur_time();                                                           \
            fprintf(stderr, "%.2u:%.2u:%.2u WRN %s():%d\t"fmt"\n",                              \
                ct / 3600, (ct % 3600) / 60, ct % 60, __FUNCTION__, __LINE__, ##__VA_ARGS__);   \
        } while(0)
#endif

#if LOG_LEVEL < LOG_LEVEL_INFO
    #define LOG_INF(fmt, ...)
#else
    #define LOG_INF(fmt, ...)                                                                   \
        do {                                                                                    \
            uint32_t ct = cur_time();                                                           \
            fprintf(stderr, "%.2u:%.2u:%.2u INF %s():%d\t"fmt"\n",                              \
                ct / 3600, (ct % 3600) / 60, ct % 60, __FUNCTION__, __LINE__, ##__VA_ARGS__);   \
        } while(0)
#endif

#if LOG_LEVEL < LOG_LEVEL_DEBUG
    #define LOG_DBG(fmt, ...)
#else
    #define LOG_DBG(fmt, ...)                                                                   \
        do {                                                                                    \
            uint32_t ct = cur_time();                                                           \
            fprintf(stderr, "%.2u:%.2u:%.2u DBG %s():%d\t"fmt"\n",                              \
                ct / 3600, (ct % 3600) / 60, ct % 60, __FUNCTION__, __LINE__, ##__VA_ARGS__);   \
        } while(0)
#endif


#endif /* UTILS_H_ */

